
#pragma once

// Qt includes
#include <QStyledItemDelegate>
#include <QSortFilterProxyModel>
#include <QWidget>

// CTK includes
//#include "ctkPimpl.h"
//#include "ctkWidgetsExport.h"

#include "RsGisLibCMD.h"

class GrsActionsWidgetPrivate;
class GrsSortFilterActionsProxyModelPrivate;

class QAction;
class QStandardItemModel;
class QStandardItem;
class QTreeView;

class GrsActionsWidget : public QWidget
{
  Q_OBJECT
  Q_PROPERTY(bool actionsWithNoShortcutVisible READ areActionsWithNoShortcutVisible WRITE setActionsWithNoShortcutVisible)
  Q_PROPERTY(bool menuActionsVisible READ areMenuActionsVisible WRITE setMenuActionsVisible)
  /// This property controls whether the actions are sorted by column (>=0) or
  /// not (-1). Not sorted by default.
  /// \sa sortColumn(), setSortColumn()
  Q_PROPERTY(int sortColumn READ sortColumn WRITE setSortColumn)
public:
  explicit GrsActionsWidget(QWidget* parent = 0);
  virtual ~GrsActionsWidget();

  /// Add an action into a specified group (or at top level if group is empty)
  /// An action can be added multiple times (in a different group). Once added,
  /// ctkActionsWidget listens to the QAction and updates the action properties
  /// TODO: check that the action hasn't been already added into a group
  void addAction(QAction* action, const QString& group = QString());
  void addActionFunction(QString functionName,
	  const QKeySequence &shortcut,
	  const QIcon &aicon,
	  QString functionType,
	  const QObject *receiver,
	  const char *member);

  /// Convenient function to add a list of action at once
  void addActions(QList<QAction*> actions, const QString& group = QString());

  /// Remove all the actions and groups
  void clear();

  /// Return a pointer on a group item (you probably have no use for it)
  QStandardItem* groupItem(const QString& category);

  /// If true, shows QActions that have an empty shortcut, otherwise hide them.
  /// True by default
  void setActionsWithNoShortcutVisible(bool show);
  bool areActionsWithNoShortcutVisible()const;

  /// If true, shows QMenus, otherwise hide them.
  /// True by default
  void setMenuActionsVisible(bool show);
  bool areMenuActionsVisible()const;

  /// Set the sortColumn property value.
  /// \sa sortColumn
  void setSortColumn(int column);
  /// Return the sortColumn property value.
  /// \sa sortColumn
  int sortColumn()const;

  /// Return the unsorted/unfiltered model of all the actions
  QStandardItemModel* model()const;

  /// return the view used to display the action model
  QTreeView* view()const;

protected Q_SLOTS:
  void updateAction();

  void itemDoubleClicked(const QModelIndex &index);
  void itemEditStarted(const QModelIndex &index);

protected:
  enum ActionColumn{
    NameColumn = 0,
    ShortcutColumn,
    ContextColumn,
    DetailsColumn
  };
protected:
  QScopedPointer<GrsActionsWidgetPrivate> d_ptr;

private:
  Q_DECLARE_PRIVATE(GrsActionsWidget);
  Q_DISABLE_COPY(GrsActionsWidget);
  friend class GrsSortFilterActionsProxyModel;

  RsGisLibCMD* rsgisHandle;
};

/// \ingroup Widgets
/// ctkSortFilterActionsProxyModel is a utility class that is needed by
/// ctkActionsWidget. It's a specialization of a QSortFilterProxyModel and
/// control what action is visible to the tree view.
class GrsSortFilterActionsProxyModel : public QSortFilterProxyModel
{
  Q_OBJECT
public:
  explicit GrsSortFilterActionsProxyModel(QObject* parent=0);
  virtual ~GrsSortFilterActionsProxyModel();

  void setActionsWithNoShortcutVisible(bool);
  bool areActionsWithNoShortcutVisible()const;

  void setMenuActionsVisible(bool);
  bool areMenuActionsVisible()const;

protected:
  bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const;
  QScopedPointer<GrsSortFilterActionsProxyModelPrivate> d_ptr;

private:
  Q_DECLARE_PRIVATE(GrsSortFilterActionsProxyModel);
  Q_DISABLE_COPY(GrsSortFilterActionsProxyModel);
};

/// \ingroup Widgets
/// ctkRichTextItemDelegate is a utility class that is needed by
/// ctkActionsWidget. It control how QAction tree items are displayed when the
/// text is written in HTML.
class GrsRichTextItemDelegate : public QStyledItemDelegate
{
  Q_OBJECT
protected:
  virtual void paint(QPainter * painter, const QStyleOptionViewItem & option,
             const QModelIndex & index) const;
  virtual QSize sizeHint(const QStyleOptionViewItem & option,
                         const QModelIndex & index)const;
};

